"use strict";

var C = require('../common'),
    ACL = require('acl');

module.exports = function (webModule, route, options, cb) {
    options = C._.extend({ prefix: 'acl_' }, options);

    if (!options.db) {
        return cb('"db" option is required!');
    }

    var dbms = options.db.split(':')[0];

    C.H.connectDb(options.db, function (db) {

        var backend;

        if (dbms === 'mongodb') {
            backend = new ACL.mongodbBackend(db, options.prefix, true);
        } else {
            return cb('Unsupported db type: ' + dbms);
        }

        var acl = new ACL(backend);

        cb(null, function (req, res, next) {

            var router = req.router;
            var auth = router.auth;

            if (!auth) {
                throw new C.Error.UsageError('Auth middleware should be enabled before using acl.');
            }

            var uid = auth.uid();
            if (!uid) {
                if (options.errorController && router.forward(options.errorController, 'unauthenticated')) {
                    return;
                }

                return router.handleError(C.HttpCode.HTTP_UNAUTHORIZED);
            }

            acl.isAllowed(uid, router.controllerPath, router.action, function (err, isAllowed) {
                if (err) {
                    return outer.handleError(err);
                }

                if (isAllowed) return next();

                if (options.errorController && router.forward(options.errorController, 'permission_denied')) {
                    return;
                }

                return router.handleError(C.HttpCode.HTTP_UNAUTHORIZED);
            });
        })
    });
};